﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Diagnostics;
using System.Threading;
using System.ComponentModel;

namespace MitutoyoRS232DataInputTool
{
    public class DataEventArgs : EventArgs
    {
        public Single NumberRead { get; set; }
        public String StringRead { get; set; }
        public String RawData { get; set; }
    }

    class RS232InputTool : INotifyPropertyChanged
    {
        SerialPort port = new SerialPort();

        public void Connect(string portName)
        {
            port.BaudRate = 2400;
            port.StopBits = StopBits.One;
            port.Handshake = Handshake.None;
            port.DataBits = 8;
            port.Parity = Parity.None;
            port.PortName = portName;
            port.DtrEnable = true;
            port.RtsEnable = true;
            port.NewLine = "\r";
            
            port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
            port.ErrorReceived += new SerialErrorReceivedEventHandler(port_ErrorReceived);
            port.PinChanged += new SerialPinChangedEventHandler(port_PinChanged);

            port.Open();

            FirePropertyChanged("IsConnected");
        }

        public bool IsConnected
        {
            get
            {
                return port.IsOpen;
            }
        }

        public event EventHandler<DataEventArgs> DataReceived;

        void port_PinChanged(object sender, SerialPinChangedEventArgs e)
        {
            //throw new NotImplementedException();
        }

        void port_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
        {
            throw new NotImplementedException();
        }

        void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            switch (e.EventType)
            {
                case SerialData.Chars:
                    ProcessData();
                    break;
                case SerialData.Eof:
                    break;
                default:
                    break;
            }
        }

        public void ProcessData()
        {
            Thread.Sleep(100);
            var raw = port.ReadExisting();

            if (raw.StartsWith("01A"))
            {
                var s = raw.Substring(3, 9);

                if (DataReceived != null)
                {
                    var args = new DataEventArgs { NumberRead = Convert.ToSingle(s), StringRead = s, RawData = raw };
                    DataReceived(this, args);
                }
            }
        }

        public void Disconnect()
        {
            port.Close();
            FirePropertyChanged("IsConnected");
        }

        public void TriggerDataRead()
        {
            port.WriteLine("1");
        }

        #region NotifyPropertyChanged

        /// <summary>
        /// Provides notification when a property's value changes.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        void FirePropertyChanged(String propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion

    }
}
